# coding: utf-8
import os
import re
from pathlib import Path

import httpx

from apitest.engine.config import main_config


class DownloadIdl:

    def __init__(self, pwd, include_psm=None, branch=None, target=None):
        self.host = "https://code.byted.org"
        self.IDL_TOKEN = os.environ.get("IDL_TOKEN")
        if not self.IDL_TOKEN:
            raise RuntimeError(
                "please set IDL_TOKEN environment variable first, follow this doc: https://dcar.feishu.cn/docx/U1V3dhtrmoD6yaxJOVmcYPpcnmh")
        target = target or "./idls"
        self.target = Path(pwd) / Path(target)
        self.client = httpx.Client(base_url=self.host, headers={'PRIVATE-TOKEN': self.IDL_TOKEN}, verify=False,
                                   timeout=60)
        self.idl_config = main_config.idl
        self.include_psm = include_psm
        self.branch = branch or "master"

    def download_thrift(self, url):
        if not url.endswith(".thrift"):
            raise RuntimeError("Only supports the thrift files, other types of files, "
                               "please go to https://cloud.bytedance.net/bam/rd to download.")
        resp = self.client.get(url)
        if resp.headers['Content-Type'] == 'text/html':
            raise RuntimeError("download thrift file failed, please check your IDL_TOKEN is well settled, follow: "
                               "https://dcar.feishu.cn/docx/U1V3dhtrmoD6yaxJOVmcYPpcnmh")
        return resp.text

    @staticmethod
    def read_thrift_rely(file_content, parent):
        rely_files = []
        includes = re.findall(r'include +"([^"\t\n]+)"', file_content)
        for include in includes:
            rely_files.append((parent / include).resolve())
        return rely_files

    def store_file(self, repo, path: Path, file_content: str):
        native_file = self.target / repo / path.relative_to("/")
        native_file.parent.mkdir(parents=True, exist_ok=True)
        with open(native_file, 'w') as fp:
            fp.write(file_content)

    def _request_related_thrift_files(self, repo, file_path):
        file_path = "/" / Path(file_path)
        url = f"{repo}/raw/{self.branch}{file_path}"
        file_content = self.download_thrift(url)
        self.store_file(Path(repo), file_path, file_content)
        rely_files = self.read_thrift_rely(file_content, file_path.parent)
        for rely in rely_files:
            self._request_related_thrift_files(file_path=rely, repo=repo)

    def request_related_thrift_files(self):
        for psm, idl in self.idl_config.items():
            if self.include_psm and psm != self.include_psm:
                continue
            self._request_related_thrift_files(idl.repo_name, idl.file_path)
